package cz.vutbr.feec.utko.mtin.regression;

import cz.vutbr.feec.utko.ef.evolution.Chromozome;
import cz.vutbr.feec.utko.ef.evolution.IFitnessEvaluator;
import cz.vutbr.feec.utko.ef.gp.tree.TreeChromozome;

public class FitnessRegression implements IFitnessEvaluator {

	private int counter = 0;
	private double[][] trainingSet;

	@Override
	public double computeFitnessValue(Chromozome ch) {
		return computeFitnessValue((TreeChromozome) ch);
	}

	public double computeFitnessValue(TreeChromozome ch) {
		counter++;
		Double sum = 0.0;
		if (this.trainingSet == null) {
			throw new RuntimeException("Training set was not specified...");
		}
		for (int i = 0; i < this.trainingSet.length; i++) {
			R1 r1 = (R1) ch.getProgramInputParameter(0);
			r1.setValue(this.trainingSet[i][0]);
			R2 r2 = (R2) ch.getProgramInputParameter(1);
			r2.setValue(this.trainingSet[i][1]);
			I1 i1 = (I1) ch.getProgramInputParameter(2);
			i1.setValue(this.trainingSet[i][2]);
			I2 i2 = (I2) ch.getProgramInputParameter(3);
			i2.setValue(this.trainingSet[i][3]);
			Double chromosomeValue = (Double) ch.getResult();
			Double measuredValue = (Double) this.trainingSet[i][4];
			Double difference = chromosomeValue - measuredValue;
			Double absValue = Math.abs(difference);
			sum += absValue;
		}
		// Fitness function is implemented as maximization function
		return 1 / sum;
	}

	@Override
	public int getNumOfEvaluations() {
		return counter;
	}

	public void addValueVector(double[][] value) {
		this.trainingSet = value;
	}
}
